package com.example.user.service;

import com.example.common.Ov.LoginOv;
import com.example.common.Ov.UserInfoOv;
import com.example.common.Ov.UserOv;
import com.example.common.entity.Const;
import com.example.common.entity.Rsp;
import com.example.common.pojo.Loan;
import com.example.common.pojo.TransCode;
import com.example.common.pojo.User;
import com.example.common.util.JWTUtil;
import com.example.common.util.P2PUtil;
import com.example.user.feign.BiddingFeign;
import com.example.user.feign.MessageFeign;
import com.example.user.mapper.TransCodeMapper;
import com.example.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService{

    @Autowired
    UserMapper userMapper;

    @Autowired
    RedisServiceImpl redisService;

    @Autowired
    MessageFeign messageFeign;

    @Autowired
    BiddingFeign biddingFeign;

    @Autowired
    TransCodeMapper transCodeMapper;

    //账号密码登录
    @Override
    public Map<String, Object> login(User user) {
        Map<String, Object> map = new HashMap<>();
        User u = userMapper.login(user);
        System.out.println(u);
        if (!StringUtils.isEmpty(u)) {
            //登录成功
            UserOv userOv = new UserOv();
            userOv.setId(u.getId());
            userOv.setAccount(u.getAccount());
            String token = JWTUtil.generateToken(userOv, Const.PRIVATE_KEY, 30);
//            return new Rsp(0,"登录成功");
            map.put("token", token);
            map.put("code", 0);
            map.put("msg", "登录成功！");
            return map;
        }

        //登录失败
//        return new Rsp(1,"登录失败");
        map.put("code", 1);
        map.put("msg", "登录失败！");
        return map;
    }

    //手机号登录
    @Override
    public Map<String, Object> login(LoginOv loginOv) {
        Map<String, Object> map = new HashMap<>();
        //从redis里面通过手机号拿出验证码
        String messageCode = (String) redisService.get(loginOv.getMobile());
        //判断验证码是否正确
        if (messageCode.equals(loginOv.getVerification())) {
            //验证码正确，去掉redis中的验证码
            redisService.remove(loginOv.getMobile());
            //获取用户（通过手机号）
            User u = userMapper.getUserByMobile(loginOv.getMobile());
            UserOv userOv = new UserOv();
            userOv.setId(u.getId());
            userOv.setAccount(u.getAccount());
            //获取token
            String token = JWTUtil.generateToken(userOv, Const.PRIVATE_KEY, 30);
            map.put("code", 0);
            map.put("token", token);
            map.put("msg", "登录成功！");
            return map;
        }
        //验证码错误
        map.put("code", 1);
        map.put("msg", "验证码错误，登录失败！");
        return map;
    }

    //根据id获取用户
    @Override
    public Rsp getUserById(Integer id) {
            UserInfoOv userInfoOv = userMapper.getById(id);
        if (!StringUtils.isEmpty(userInfoOv)) {
            //获取成功
            System.out.println(userInfoOv);
            return new Rsp(0, userInfoOv, "获取成功");
        }
        //获取失败
        return new Rsp(1, "获取失败");
    }

    //通过手机号获取用户信息（登录）
    @Override
    public Rsp getUserByMobile(String mobile) {
        User user = userMapper.getUserByMobile(mobile);
        if (!StringUtils.isEmpty(user)) {
            //可以登录
            LoginOv loginOV = new LoginOv();
            loginOV.setMobile(mobile);
            //调用发送验证码的方法
            loginOV.setVerification(P2PUtil.generateCode());
            System.out.println(loginOV.getVerification());
            return messageFeign.getMessageCode(loginOV);
        }
        //不可以登录
        return new Rsp(1, "该手机号未注册！请前往注册！");
    }

    /**
     * 校验用户名，密码，邮箱
     */
    @Override
    public Rsp checkAccountPwdEmail(User user) {
        //校验账号是否存在
        User u1 = new User();
        u1.setAccount(user.getAccount());
        UserInfoOv uu1 = userMapper.getUserByCondition(u1);
        if (!StringUtils.isEmpty(uu1)) {
            //账号已存在，不能注册
            return new Rsp(0, "账号已注册");
        }
        //校验邮箱
        User u2 = new User();
        u2.setEmail(user.getEmail());
        UserInfoOv uu2 = userMapper.getUserByCondition(u2);
        if (!StringUtils.isEmpty(uu2)) {
            //邮箱已存在，不能注册
            return new Rsp(0, "邮箱已注册");
        }
        return new Rsp(0, "注册成功");
    }

    public int subBalance(User user, BigDecimal cost) {
        user.setBalance(user.getBalance().subtract(cost));
        return userMapper.updateByPrimaryKeySelective(user);
    }

    /**
     * 流标退款
     * @param borrowId
     * @return
     */
    @Transactional
    public int refund(Integer borrowId) {
        List<Loan> loanList = biddingFeign.getPaiedLoanByBorrowId(borrowId);
        for (Loan loan : loanList) {
            User user = userMapper.selectByPrimaryKey(loan.getUserId());
            //退款
            user.setBalance(user.getBalance().add(loan.getLoanMoney()));
            userMapper.updateByPrimaryKeySelective(user);

            //发一条通知
            TransCode transCode = new TransCode();
            transCode.setUserId(loan.getUserId());
            transCode.setType("退款");
            transCode.setContent("您的出借款"+loan.getNo()+"未筹集完成，已发起退款");
            transCodeMapper.insertSelective(transCode);
        }
        return 1;
    }
    //用户注册
    @Override
    public Rsp register(User user) {
        //先判断该身份证是否已经注册
        User u = new User();
        u.setIdCard(user.getIdCard());
        UserInfoOv userInfo = userMapper.getUserByCondition(u);
        if(!StringUtils.isEmpty(userInfo)){
            //不为空代表已注册，该身份证注册失败
            return new Rsp(0,"该身份证已经被注册！");
        }
        //其次再注册
        int i = userMapper.insertSelective(user);
        return i>0?new Rsp(0,"注册成功"):new Rsp(0,"注册失败，请稍后重试");
    }

    //修改个人信息
    @Override
    public Rsp updateMyself(User user) {
        String addr = user.getProvince()+user.getCity()+user.getArea();
        user.setAddress(addr);
        int result = userMapper.updateByPrimaryKeySelective(user);
        return result>0?new Rsp(0,"修改成功"):new Rsp(0,"修改失败");
    }

    //获取验证码（验证银行卡）
    @Override
    public Rsp getCode(String mobile) {
        LoginOv loginOV = new LoginOv();
        loginOV.setMobile(mobile);
        loginOV.setVerification(P2PUtil.generateCode());
        return messageFeign.getMessageCode(loginOV);
    }

    //充值
    @Override
    public Rsp recharge(UserOv userOv, User user) {
        //给账户充值
        //查询原有金额
        UserInfoOv u = userMapper.getById(userOv.getId());
        User uu = new User();
        uu.setId(userOv.getId());
        uu.setBalance(u.getBalance().add(user.getBalance()));
        int i = userMapper.updateByPrimaryKeySelective(uu);
        if(i>0){
            //充值后添加充值记录
            TransCode transCode = new TransCode();
            transCode.setUserId(userOv.getId());
            transCode.setType("充值");
            String c = "您刚刚"+transCode.getType()+"了"+user.getBalance()+"元，当前余额："+uu.getBalance()+"元";
            transCode.setContent(c);
            int result = transCodeMapper.insertSelective(transCode);
            return new Rsp(0,"充值成功");
        }
        return new Rsp(0,"充值失败");
    }

    //提现
    @Override
    public Rsp withdrawal(UserOv userOv, User user) {
        //提现
        UserInfoOv u = userMapper.getById(userOv.getId());
        //判断余额是否足够
        if(u.getBalance().compareTo(user.getBalance()) < 0){
            //余额不足
            return new Rsp(0,"余额不足");
        }
        User uu = new User();
        uu.setId(userOv.getId());
        uu.setBalance(u.getBalance().subtract(user.getBalance()));
        int i = userMapper.updateByPrimaryKeySelective(uu);
        if(i>0){
            //提现成功，添加记录
            TransCode transCode = new TransCode();
            transCode.setUserId(userOv.getId());
            transCode.setType("提现");
            String c = "您刚刚"+transCode.getType()+"了"+user.getBalance()+"元，当前余额："+uu.getBalance()+"元";
            transCode.setContent(c);
            int result = transCodeMapper.insertSelective(transCode);
            return new Rsp(0,"提现成功");
        }
        return new Rsp(0,"提现失败");
    }

    public int addBalance(Integer id, BigDecimal cost) {
        User user = userMapper.selectByPrimaryKey(id);
        user.setBalance(user.getBalance().add(cost));
        return userMapper.updateByPrimaryKeySelective(user);
    }
}
